#!/usr/bin/env python3
# -*- coding: utf-8 -*-
''' Simplify Yuketang quiz's progress.
:author Tiger3018
:date 2020-12-09
:updated 2022-10-29
'''
from requests import Session
from time import sleep
import os, traceback, json, csv, re, collections
import xml.etree.ElementTree as xet
# e.exerciseList.problems
# https://courses.cqu.edu.cn/mooc-api/v1/lms/exercise/get_exercise_list/869121/

workDir = "work"

def jsonParse(dataPath, mod = 0):
    if mod:
        with open(dataPath, "r") as fileIO:
            data = fileIO.read()
            try:
                dataParse = json.loads(data)
            except Exception as e:
                traceback.print_exc()
                return 0
    else:
        data = dataPath
        try:
            dataParse = json.loads(data)
        except Exception as e:
            traceback.print_exc()
            return 0
    if ("success" in dataParse) and dataParse["success"]:
        return dataParse
    else:
        return 0

def yukeStr(str):
    if re_result := re.search(r"(?<=<p>)(.|\r|\n)*(?=</p>)", str, re.DOTALL):
        return re_result.group().replace("\n", "")
    else:
        return re.search(r"(.|\r|\n)*", str, re.DOTALL).group().replace("\n", "")

def yukeParse(dataParse, prId):
    # print(dataParse["success"])
    try:
        title = dataParse["data"]["description"] + " - " + dataParse["data"]["name"]
        prList = dataParse["data"]["problems"]
        i = 0
        dictd = []
        for prItem in prList:
            dictd.append( [] )
            dictd[i].append( '/'.join(prItem["user"]["answer"]) )
            dictd[i].append( yukeStr(prItem["content"]["Body"]) )
            j = 2
            for prOpti in prItem["content"]["Options"]:
                dictd[i].append( yukeStr(prOpti["value"]) if prOpti["value"] else prOpti["key"] ) # Since items are sorted by key
                j += 1
            i += 1
        # print(title)
    except Exception as e:
        traceback.print_exc()
        return 1
    # print(dictd)
    try:
        with open(workDir + "/" + str(prId) + ".csv", "w", newline='', encoding="utf-8") as csvIO:
            csvOb = csv.writer(csvIO)
            csvOb.writerow([title])
            csvOb.writerows(dictd)
    except Exception as e:
        traceback.print_exc()
        return 1
    return 0
    
def csvLink(naList):
    lenCo = 8
    dictd = [
        ["正确答案", "题干", "选项A", "选项B", "选项C", "选项D", "选项E", "选项F"]
    ]
    try:
        print(dictd)
        for i in naList:
            dataName = str(i) + ".csv"
            dataPath = workDir + "/" + dataName
            with open(dataPath, "r", encoding="utf-8") as csvIO:
                csvOb = csv.reader(csvIO)
                dictd.append( [i] + [j for j in next(csvOb)] + ["N/A" for i in range(lenCo - 2)] )
                for csvLi in csvOb:
                    dictd.append(csvLi + ["N/A" for i in range(lenCo - len(csvLi))])
        dataPath = workDir + "/" + "fruits.csv"
        with open(dataPath, "w", newline='', encoding="utf-8") as csvIO:
            csvOb = csv.writer(csvIO, dialect="excel")
            csvOb.writerows(dictd)
    except Exception:
        traceback.print_exc()


def __init__():
    """
    A Loop for question courses in [proS, proE] with requests&cookies.
    
    Each loop will manage to get "sucess":true json file.
    """
    # proS = 869112
    # proE = 869127
    # proE = 869127
    # proList = [1600010,1600017,1600026,1600033,1600042,1600049,1600056,1600065,1600078,1600094,1600107,1600120,1600136,1600155,1600174,1600189]
    # proList = [27394756, 27394846, 27394948, 27395040, 27395071, 27395090, 27395141, 27395160, 27395176, 27395199, 27395227, 27395251, 27395280, 27395288]
    proList = [2580769, 2580777, 2580786, 2580794, 2580798, 2580800, 2580802, 2580804, 2580806, 2580808, 2580810, 2580812, 2580814, 2580816, 2580818]
    urlPre = "https://courses.cqu.edu.cn/mooc-api/v1/lms/exercise/get_exercise_list/"
    # payload = {"cookies":"=; =2930; platform_id=3; ", }
    reqSe = Session()
    reqSe.cookies.set("sessionid", "!TODO!") # = {"sessionid":"!TODO!", "university_id": "2930"}
    # https://courses.cqu.edu.cn/c27/online_courseware/schedule/score_detail/single/3040944/0
    for i in proList:
        # do something
        # print(i)
        dataName = str(i) + ".json"
        dataPath = workDir + "/" + dataName
        if not (os.path.exists(dataPath) and (jsonData := jsonParse(dataPath, 1))):
            try:
                while 1 or sleep(.5):
                    dataReceive = reqSe.get(urlPre + str(i), headers={"xtbz": "cloud"})
                    if dataReceive.status_code == 200 and (jsonData := jsonParse(dataReceive.content)):
                        break
                    print("[GET] status code " + str(dataReceive.status_code) + " or invalid data |" + str(i))
                with open(dataPath, "wb") as fileDo:
                    fileDo.write(dataReceive.content)
            except Exception as e:
                traceback.print_exc()
            # print(urlPre + str(i))
        yukeParse(jsonData, i)
    csvLink(proList)
    return 0

if not os.path.exists(workDir):
    os.makedirs(workDir)
__init__()